package com.techsoul.module.baoli.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.techsoul.common.core.exception.BusinessException;
import com.techsoul.common.core.exception.ParamException;
import com.techsoul.common.core.pojo.vo.UserVo;
import com.techsoul.common.core.util.ServletUtils;
import com.techsoul.common.core.util.bean.BeanUtils;
import com.techsoul.common.core.util.collection.ListUtils;
import com.techsoul.common.core.util.id.IdWorker;
import com.techsoul.common.core.util.lang.NumberUtils;
import com.techsoul.common.security.service.TokenService;
import com.techsoul.module.accounting.enmus.AccountingStatusEnum;
import com.techsoul.module.accounting.mapper.AccountingApMapper;
import com.techsoul.module.accounting.mapper.AccountingArMapper;
import com.techsoul.module.accounting.mapper.FinPlatformChargeMapper;
import com.techsoul.module.accounting.pojo.entity.AccountingAp;
import com.techsoul.module.accounting.pojo.entity.AccountingAr;
import com.techsoul.module.accounting.pojo.entity.FinPlatformCharge;
import com.techsoul.module.accounting.pojo.param.FinPlatformChargeSearchParam;
import com.techsoul.module.accounting.pojo.vo.FinPlatformChargeVo;
import com.techsoul.module.baoli.enmus.FinFinanceApplyEnum;
import com.techsoul.module.baoli.mapper.FinCurrentRateMapper;
import com.techsoul.module.baoli.mapper.FinFinanceApplyMapper;
import com.techsoul.module.baoli.pojo.entity.FinCurrentRate;
import com.techsoul.module.baoli.pojo.entity.FinFinanceApply;
import com.techsoul.module.baoli.pojo.param.FinFinanceApplySaveParam;
import com.techsoul.module.baoli.pojo.param.FinFinanceApplySearchParam;
import com.techsoul.module.baoli.pojo.vo.FinFinanceApplyVo;
import com.techsoul.module.baoli.service.IFinFinanceApplyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 融资申请单 Service实现
 *
 * @author liuen
 * @date 2022-03-28
 */
@Service
@Transactional(readOnly = true)
public class FinFinanceApplyServiceImpl implements IFinFinanceApplyService {

    @Autowired
    private IdWorker idWorker;

    @Autowired
    private FinFinanceApplyMapper mapper;
    @Autowired
    private FinCurrentRateMapper rateMapper;
    @Autowired
    private FinPlatformChargeMapper chargeMapper;
    @Autowired
    private AccountingApMapper accountingApMapper;
    @Autowired
    private AccountingArMapper accountingArMapper;
    @Autowired
    private TokenService tokenService;

    /**
     * 新增
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String insert(FinFinanceApplySaveParam params) {
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        FinFinanceApply entity = new FinFinanceApply();
        BeanUtils.copyProperties(params, entity);
        entity.setId(idWorker.nextId() + "").preInsert(user.getId());
        this.mapper.insert(entity);
        return entity.getId();
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer delete(String id) {
        return this.mapper.deleteById(id);
    }

    /**
     * 批量删除
     * @param idList
     */
    @Transactional(readOnly = false)
    @Override
    public Integer batchDelete(List<String> idList) {
        if (ListUtils.isNotEmpty(idList)) {
            return this.mapper.deleteBatchIds(idList);
        } else {
            return 0;
        }
    }

    /**
     * 修改
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public Integer update(FinFinanceApplySaveParam params) {
        FinFinanceApply entityFromDb = this.mapper.selectById(params.getId());
        if (entityFromDb == null) {
            throw new ParamException("id=" + params.getId());
        }
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        BeanUtils.copyProperties(params, entityFromDb);
        entityFromDb.preUpdate(user.getId());
        return this.mapper.updateById(entityFromDb);
    }

    /**
     * 详情
     * @param id
     * @return
     */
    @Override
    public FinFinanceApplyVo findById(String id) {
        return this.mapper.findById(id);
    }

    /**
     * 列表
     * @param params
     * @return
     */
    @Override
    public List<FinFinanceApplyVo> findAll(FinFinanceApplySearchParam params) {
        return this.mapper.findAll(params);
    }
    /**
     *结算确认
     * @param params
     * @return
     */
    @Transactional(readOnly = false)
    @Override
    public String settlementConfirm(FinFinanceApplySaveParam params){
        String ret = "success";
        List<String> ids = params.getIds();
        List<AccountingAr> AccountingArs = new ArrayList<AccountingAr>();
        List<AccountingAp> AccountingAps = new ArrayList<AccountingAp>();
        UserVo user = tokenService.getLoginUser(ServletUtils.getRequest()).getUser();
        FinPlatformChargeSearchParam finPlatformChargeSearchParam =new FinPlatformChargeSearchParam();
        List<FinPlatformChargeVo> charges = this.chargeMapper.findAll(finPlatformChargeSearchParam);
        for(int i=0;i<ids.size();i++){
            FinFinanceApply finFinanceApply = this.mapper.selectById((String)ids.get(i));
            List<FinCurrentRate> rates = this.rateMapper.findByProviderNo(finFinanceApply.getBaoliSite(),finFinanceApply.getFinanceDays());
            if(rates!=null&&rates.size()>0){
                FinCurrentRate rate = (FinCurrentRate)rates.get(0);
                double amt = NumberUtils.mul(finFinanceApply.getFinanceAmt(),rate.getInterestRate());
                double accurePayment = NumberUtils.sub(finFinanceApply.getFinanceAmt(),amt);
                double serviceCharges = 0.0;

                AccountingAr arToBaoliProvider = new AccountingAr(); // 未来保理公司应收款
                arToBaoliProvider.setAmount(finFinanceApply.getFinanceAmt());
                arToBaoliProvider.setBasicNo(finFinanceApply.getBasicNo());
                arToBaoliProvider.setBatchWorkorderNo(finFinanceApply.getContractNo());
                arToBaoliProvider.setInvoiceNo(finFinanceApply.getInvoiceNo());  arToBaoliProvider.setBillNo(finFinanceApply.getFinanceOrderNo());

                arToBaoliProvider.setBizKind("HK");
                arToBaoliProvider.setBizUnit("HK");
                arToBaoliProvider.setBranchUnit(user.getOrgName());
                arToBaoliProvider.setCargoObjectName(finFinanceApply.getProductName());
                arToBaoliProvider.setCargoObjectNo(finFinanceApply.getProductNo());
                arToBaoliProvider.setFrtCd("101");
                arToBaoliProvider.setFrtNm("还款");
                arToBaoliProvider.setStatus(AccountingStatusEnum.CREATED.getStatus());
                arToBaoliProvider.setSite(finFinanceApply.getFinanceProvideCompanyNo());
                arToBaoliProvider.setPayCust(finFinanceApply.getFinanceProvideCompanyNo());
                arToBaoliProvider.setShipperName(finFinanceApply.getFinanceProvideCompanyName());
                arToBaoliProvider.setBillToCust(finFinanceApply.getFinanceApplyCompanyNo());
                arToBaoliProvider.setBillToCustName(finFinanceApply.getFinanceApplyCompany());
                arToBaoliProvider.setId(idWorker.nextId() + "").preInsert(user.getId());
                AccountingArs.add(arToBaoliProvider);

                AccountingAp apToBaoli = new AccountingAp(); //未来买家公司应付款给保理
                apToBaoli.setAmount(finFinanceApply.getFinanceAmt());
                apToBaoli.setBasicNo(finFinanceApply.getBasicNo());
                apToBaoli.setBatchWorkorderNo(finFinanceApply.getContractNo());
                apToBaoli.setInvoiceNo(finFinanceApply.getInvoiceNo());
                apToBaoli.setBillNo(finFinanceApply.getFinanceOrderNo());
                //apToBaoli.setBillToCust("买家公司付款");
                apToBaoli.setBizKind("BAMT");
                apToBaoli.setBizUnit("BAMT");
                apToBaoli.setSettlementId(arToBaoliProvider.getId());
                apToBaoli.setBranchUnit(user.getOrgName());
                apToBaoli.setCargoObjectName(finFinanceApply.getProductName());
                apToBaoli.setCargoObjectNo(finFinanceApply.getProductNo());
                apToBaoli.setFrtCd("208");
                apToBaoli.setFrtNm("买家公司付款");
                apToBaoli.setStatus(AccountingStatusEnum.CREATED.getStatus());
                apToBaoli.setSite(finFinanceApply.getFinanceApplyCompanyNo());
                apToBaoli.setPayCust(finFinanceApply.getFinanceApplyCompanyNo());
                apToBaoli.setStoreName(finFinanceApply.getFinanceApplyCompany());

                apToBaoli.setBillToCust(finFinanceApply.getFinanceProvideCompanyNo());
                apToBaoli.setBillToCustName(finFinanceApply.getFinanceProvideCompanyName());

                apToBaoli.setId(idWorker.nextId() + "").preInsert(user.getId());
                AccountingAps.add(apToBaoli);
                for(int j=0;j<charges.size();j++){
                    FinPlatformChargeVo finPlatformChargeVo = (FinPlatformChargeVo)charges.get(j);
                    if(finPlatformChargeVo.getPlatformServiceChargeRateOrAmt().equals("amt")){
                        serviceCharges = serviceCharges + finPlatformChargeVo.getPlatformServiceChargeFee();
                    }else{
                        double serviceFee = NumberUtils.mul(finFinanceApply.getFinanceAmt(),finPlatformChargeVo.getPlatformServiceChargeRate());
                        serviceCharges = serviceCharges + serviceFee;
                    }
                    AccountingAr arByPlatform = new AccountingAr();//平台应收
                    arByPlatform.setAmount(serviceCharges);
                    arByPlatform.setBasicNo(finFinanceApply.getBasicNo());
                    arByPlatform.setBatchWorkorderNo(finFinanceApply.getContractNo());
                    arByPlatform.setInvoiceNo(finFinanceApply.getInvoiceNo());
                    arByPlatform.setBillNo(finFinanceApply.getFinanceOrderNo());
                    // arByPlatform.setBillToCust(finFinanceApply.getFinanceProvideCompanyName());
                    arByPlatform.setBizKind("PT");
                    arByPlatform.setBizUnit("PT");
                    arByPlatform.setBranchUnit(user.getOrgName());
                    arByPlatform.setCargoObjectName(finFinanceApply.getProductName());
                    arByPlatform.setCargoObjectNo(finFinanceApply.getProductNo());
                    arByPlatform.setFrtCd("102");
                    arByPlatform.setFrtNm("平台服务费");
                    arByPlatform.setStatus(AccountingStatusEnum.CREATED.getStatus());
                    arByPlatform.setSite("1");

                    arByPlatform.setPayCust("1");
                    arByPlatform.setShipperName("平台");
                    arByPlatform.setBillToCust(finFinanceApply.getFinanceApplyCompanyNo());
                    arByPlatform.setBillToCustName(finFinanceApply.getFinanceApplyCompany());

                    arByPlatform.setId(idWorker.nextId() + "").preInsert(user.getId());
                    AccountingArs.add(arByPlatform);

                    AccountingAp apToApplicate = new AccountingAp(); //付款 by baoli 服务费
                    apToApplicate.setAmount(serviceCharges);
                    apToApplicate.setBasicNo(finFinanceApply.getBasicNo());
                    apToApplicate.setBatchWorkorderNo(finFinanceApply.getContractNo());
                    apToApplicate.setInvoiceNo(finFinanceApply.getInvoiceNo());
                    apToApplicate.setBillNo(finFinanceApply.getFinanceOrderNo());
                    apToApplicate.setBillToCust("平台服务费");
                    apToApplicate.setBizKind("PT");
                    apToApplicate.setBizUnit("PT");
                    apToApplicate.setSettlementId(arByPlatform.getId());
                    apToApplicate.setBranchUnit(user.getOrgName());
                    apToApplicate.setCargoObjectName(finFinanceApply.getProductName());
                    apToApplicate.setCargoObjectNo(finFinanceApply.getProductNo());
                    apToApplicate.setFrtCd("202");
                    apToApplicate.setFrtNm("平台服务费");
                    apToApplicate.setStatus(AccountingStatusEnum.CREATED.getStatus());
                    apToApplicate.setSite(finFinanceApply.getFinanceApplyCompanyNo());

                    apToApplicate.setPayCust(finFinanceApply.getFinanceApplyCompanyNo());
                    apToApplicate.setStoreName(finFinanceApply.getFinanceProvideCompanyName());
                    apToApplicate.setBillToCust("1");
                    apToApplicate.setBillToCustName("平台");

                    apToApplicate.setId(idWorker.nextId() + "").preInsert(user.getId());
                    AccountingAps.add(apToApplicate);
                }
                AccountingAr arByApplicate = new AccountingAr(); //要加上扣款明细 by 融资人。要加上减去平台服务费 serviceCharges
                arByApplicate.setAmount(accurePayment);
                arByApplicate.setBasicNo(finFinanceApply.getBasicNo());
                arByApplicate.setInvoiceNo(finFinanceApply.getInvoiceNo());
                arByApplicate.setBatchWorkorderNo(finFinanceApply.getContractNo());
                arByApplicate.setBillNo(finFinanceApply.getFinanceOrderNo());

                arByApplicate.setBizKind("DZ");
                arByApplicate.setBizUnit("DZ");
                arByApplicate.setBranchUnit(user.getOrgName());
                arByApplicate.setCargoObjectName(finFinanceApply.getProductName());
                arByApplicate.setCargoObjectNo(finFinanceApply.getProductNo());
                arByApplicate.setFrtCd("203");
                arByApplicate.setFrtNm("垫资收款");
                arByApplicate.setStatus(AccountingStatusEnum.CREATED.getStatus());
                arByApplicate.setSite(finFinanceApply.getFinanceApplyCompanyNo());

                arByApplicate.setPayCust(finFinanceApply.getFinanceApplyCompanyNo());
                arByApplicate.setShipperName(finFinanceApply.getFinanceApplyCompany());
                arByApplicate.setBillToCust(finFinanceApply.getFinanceProvideCompanyNo());
                arByApplicate.setBillToCustName(finFinanceApply.getFinanceProvideCompanyName());

                arByApplicate.setId(idWorker.nextId() + "").preInsert(user.getId());
                AccountingArs.add(arByApplicate);

                AccountingAp apToApplicate = new AccountingAp(); //付款 收by baoli
                apToApplicate.setAmount(accurePayment);
                apToApplicate.setBasicNo(finFinanceApply.getBasicNo());
                apToApplicate.setBatchWorkorderNo(finFinanceApply.getContractNo());
                apToApplicate.setInvoiceNo(finFinanceApply.getInvoiceNo());
                apToApplicate.setBillNo(finFinanceApply.getFinanceOrderNo());

                apToApplicate.setBizKind("DZ");
                apToApplicate.setBizUnit("DZ");
                apToApplicate.setBranchUnit(user.getOrgName());
                apToApplicate.setCargoObjectName(finFinanceApply.getProductName());
                apToApplicate.setCargoObjectNo(finFinanceApply.getProductNo());
                apToApplicate.setFrtCd("103");
                apToApplicate.setSettlementId(arByApplicate.getId());
                apToApplicate.setFrtNm("垫资付款");
                apToApplicate.setStatus(AccountingStatusEnum.CREATED.getStatus());
                apToApplicate.setSite(finFinanceApply.getFinanceProvideCompanyNo());

                apToApplicate.setPayCust(finFinanceApply.getFinanceProvideCompanyNo());
                apToApplicate.setStoreName(finFinanceApply.getFinanceProvideCompanyName());
                apToApplicate.setBillToCust(finFinanceApply.getFinanceApplyCompanyNo());
                apToApplicate.setBillToCustName(finFinanceApply.getFinanceApplyCompany());

                apToApplicate.setId(idWorker.nextId() + "").preInsert(user.getId());
                AccountingAps.add(apToApplicate);


                finFinanceApply.setStatus(FinFinanceApplyEnum.settled.getValue());
                finFinanceApply.preUpdate(user.getId());
                this.mapper.updateById(finFinanceApply);
            }else{
                throw new BusinessException("结算利息没有查到，请先添加相关利息数据");
            }
        }
        for(int j=0;j<AccountingArs.size();j++){
            AccountingAr accountingAr = (AccountingAr)AccountingArs.get(j);
            this.accountingArMapper.insert(accountingAr);
        }
        for(int k=0;k<AccountingAps.size();k++){
            AccountingAp accountingAp = (AccountingAp)AccountingAps.get(k);
            this.accountingApMapper.insert(accountingAp);
        }
        return ret;
    }
    /**
     * 列表-分页
     * @param params
     * @param current
     * @param pageSize
     * @return
     */
    @Override
    public IPage<FinFinanceApplyVo> findAll(FinFinanceApplySearchParam params, Integer current, Integer pageSize) {
        return this.mapper.findAll(new Page<>(current, pageSize), params);
    }

}
